import {
    Button, Color, Label, LabelOutline, LabelShadow, Node, ParticleSystem2D, Size, size, Sprite,
    UITransform, v2, Vec2, Vec3
} from 'cc';
import { PREVIEW } from 'cc/env';

/**
 * cocos的一些方法封装
 */
export namespace UtilCocos {

    /**
     * 获取节点UITransform组件
     * 不存在则添加该组件
     */
    function getNodeUITransform(node: Node): UITransform {
        if (!node || !node.isValid) return null;
        const uitf: UITransform = node.getComponent(UITransform) || node.addComponent(UITransform);
        return uitf;
    }

    /**
     * 获取节点世界坐标, 失败返回null
     * @param node 
     * @param defPos 默认坐标
     * @returns 
     */
    export function getNodeWPos(node: Node, defPos?: Vec3): Vec3 {
        const uitf: UITransform = getNodeUITransform(node);
        if (uitf) {
            return uitf.convertToWorldSpaceAR(Vec3.ZERO);
        }

        if (defPos == undefined || defPos == null)
            return null;
        else
            return defPos;
    }

    /**
     * 修改节点尺寸 
     */
    export function setNodeSize(node: Node, width: number | Size, height?: number) {
        const uitf: UITransform = getNodeUITransform(node);
        if (!uitf) return;
        const a: Size = typeof width === "number" ? size(width, height || 0) : width;
        uitf.setContentSize(a);
    }

    /**
     * 修改节点锚点
     */
    export function setNodeAnchorPoint(node: Node, x: number | Vec2, y?: number) {
        const uitf: UITransform = getNodeUITransform(node);
        if (!uitf) return;
        const a: Vec2 = typeof x === "number" ? v2(x, y || 0) : x;
        uitf.setAnchorPoint(a);
    }

    /**
     * 设置图片节点灰化状态
     * @param target 对象节点
     * @param gray 是否灰态
     * @param btnInteract 是否修改按钮响应
     * @returns 
     */
    export function setNodeGray(target: Node, gray: boolean, btnInteract: boolean = true) {
        if (!target || !target.isValid)
            return;

        const sprite = target.getComponent(Sprite);
        if (sprite) sprite.grayscale = gray;

        const txt = target.getComponent(Label);
        if (txt) {
            // check
            const isTxtGray = target["isTxtGray"] || false;
            if (isTxtGray == gray)
                return;
            let txtColor = '';
            if (gray) {
                txtColor = txt.color.toHEX("#rrggbbaa");
                target.attr({ txtColor });
                txt.color = grayColor(txt.color);
            }
            else {
                txtColor = target["txtColor"];
                if (txtColor && txtColor.length > 0)
                    txt.color = new Color().fromHEX(txtColor);
            }
            target.attr({ isTxtGray: gray });
            // 文本的描边
            const outLine = target.getComponent(LabelOutline);
            if (outLine) {
                let outLineColor = '';
                if (gray) {
                    outLineColor = outLine.color.toHEX("#rrggbbaa");
                    target.attr({ outLineColor });
                    outLine.color = grayColor(outLine.color);
                }
                else {
                    outLineColor = target["outLineColor"];
                    if (outLineColor && outLineColor.length > 0)
                        outLine.color = new Color().fromHEX(outLineColor);
                }
            }
            // 文本的阴影
            const shadow = target.getComponent(LabelShadow);
            if (shadow) {
                let shadowColor = '';
                if (gray) {
                    shadowColor = shadow.color.toHEX("#rrggbbaa");
                    target.attr({ shadowColor });
                    shadow.color = grayColor(shadow.color);
                }
                else {
                    shadowColor = target["shadowColor"];
                    if (shadowColor && shadowColor.length > 0)
                        shadow.color = new Color().fromHEX(shadowColor);
                }
            }
        }

        if (btnInteract) {
            const btn = target.getComponent(Button);
            if (btn) btn.interactable = !gray;
        }

        target.children.forEach(nd => setNodeGray(nd, gray));
    }
    /** Color灰度设置 */
    function grayColor(color: Color): Color {
        let v = color.r * 0.299 + color.g * 0.587 + color.b * 0.114;
        v = Math.round(v);
        const result = new Color(v, v, v);
        PREVIEW && console.log(`[grayColor] 原色:${color.toHEX("#rrggbb")}, 灰化:${result.toHEX("#rrggbb")}`);
        return result;
    }

    /**
     * 更新节点下所有粒子组件状态
     */
    export function setParticle(node: Node, play: boolean) {
        if (!node || !node.isValid)
            return;

        const par = node.getComponent(ParticleSystem2D);
        if (par) {
            play ? par.resetSystem() : par.stopSystem();
        }

        node.children.forEach(nd => setParticle(nd, play));
    }

}